package com.datastructures.stack;

/**
 * @author MaoLin Wang
 * @date 2019/10/2113:29
 */
public class Calculator {
    public static void main(String[] args) {
        String expression="3+2*6-2";
        ArrayStack2 numStack = new ArrayStack2(10);
        ArrayStack2 operStack = new ArrayStack2(10);
        int index=0;//用于扫描
        int num1=0;
        int num2=0;
        int oper=0;
        int res=0;
        char ch=' ';
        String keepnum="";
        //开始while
        while (true){
            ch=expression.substring(index,index+1).charAt(0);
            //判断ch是什么，然后做出相应的处理
            if(operStack.isOper(ch)){
                if(operStack.isEmpty()){
                    //运算符栈为空
                    operStack.push(ch);
                }else {
                    //不为空,比较优先级
                    if (operStack.priority(ch)<=operStack.priority(operStack.pick())){
                        //优先级低于栈顶操作符
                        num1 =numStack.pop();
                        num2 = numStack.pop();
                        oper=operStack.pop();
                        res=numStack.cal(num1,num2,oper);
                        //运算结果加入栈
                        numStack.push(res);
                        //当前操作符入符号栈
                        operStack.push(ch);
                    }else {
                        //优先级大于栈顶操作符
                        operStack.push(ch);

                    }
                }
            }else {
                //是数字
                //numStack.push( ch-48);
                //处理多位数
                keepnum+=ch;
                if(index == expression.length()-1){
                    numStack.push(Integer.parseInt(keepnum));
                }else {
                    //判断下一个是不是数字，如果是就继续扫描，否则，入栈
                    if(operStack.isOper(expression.substring(index+1,index+2).charAt(0))){
                        numStack.push(Integer.parseInt(keepnum));
                        keepnum="";
                    }
                }

            }
            //让index+1，并判断是否扫描到expression最后
            index++;
            if(index >=expression.length()){
                break;
            }
        }
        //顺序取出数据和符号运算
        while (true){
            //如果符号栈为空，则计算到最后的结果,数栈只有一个数字[结果]
            if(operStack.isEmpty()){
                break;
            }else {
                num1 =numStack.pop();
                num2 = numStack.pop();
                oper=operStack.pop();
                res=numStack.cal(num1,num2,oper);
                numStack.push(res);
            }
        }
        System.out.println("结果为："+numStack.pop());
    }
}

/**
 *
 */
class ArrayStack2 {
    private int maxSize;
    private int[] stack;//数组模拟栈，数据就放在该数组
    private int top = -1;//top表示栈顶，初始化为-1

    public ArrayStack2(int maxSize) {
        this.maxSize = maxSize;
        stack = new int[this.maxSize];
    }

    //栈满
    public boolean isFull() {
        return top == maxSize - 1;
    }

    public boolean isEmpty() {
        return top == -1;
    }

    public void push(int value) {
        if (isFull()) {
            System.out.println("栈满");
            return;
        }
        top++;
        stack[top] = value;
    }

    public int pop() {
        if (isEmpty()) {
            throw new RuntimeException("栈空");
        }
        int value = stack[top];
        top--;
        return value;
    }

    //返回运算符的优先级，优先级是自定义的，优先级使用数字表示
    // 数字越大，优先级越高
    public int priority(int oper){
        if(oper == '*' || oper == '/' ){
            return 1;
        }else if(oper == '+' || oper == '-'){
            return 0;
        }else {
            return -1;//假定目前表达式只有+ - * /
        }
    }

    //判断是不是一个运算符
    public boolean isOper(char val){
        return val == '+'||val=='-'||val=='*'||val=='/';
    }
    //计算方法
    public int cal(int num1,int num2,int oper){
        int res=0;//存放计算的结果
        switch (oper){
            case '+':
                res = num1+num2;
                break;
            case '-':
                res=num2-num1;
                break;
            case '/':
                res=num2/num1;
                break;
            case '*':
                res=num1*num2;
                default:
                    break;
        }
        return res;
    }

    /**
     * 返回栈顶的值，不是真正的pop
     */
    public int pick(){
        return stack[top];
    }
    //遍历
    public void printData() {
        if (isEmpty()) {
            System.out.println("栈空");
            return;
        }
        for (int i = top; i >= 0; i--) {
            System.out.println(stack[i]);
        }
    }
}
